import * as pattern from '@/common/pattern';
import * as c from '@/services/consts';
import * as api from '@/services/vpnServer';
import { CheckSquareOutlined, EyeFilled } from '@ant-design/icons';
import ProForm, {
  DrawerForm,
  ProFormDateTimePicker,
  ProFormDigit,
  ProFormInstance,
  ProFormSelect,
  ProFormSwitch,
  ProFormText,
  ProFormTextArea,
  ProFormTreeSelect,
} from '@ant-design/pro-form';
import type {
  ActionType,
  EditableFormInstance,
  ProColumns,
} from '@ant-design/pro-table';
import { EditableProTable } from '@ant-design/pro-table';
import { Button, Col, Popconfirm, Row, Space, message } from 'antd';
import dayjs from 'dayjs';
import React, { useRef, useState } from 'react';
import { useModel } from 'umi';
import VpnServerBatchRemarkForm from './BatchChangeRemarkForm';
import BatchVpnServerIpForm from './BatchVpnServerIpForm';
import BatchVpnServerOutIpForm from './BatchVpnServerOutIpForm';
import VpnServerChangeIpLogForm from './VpnServerChangeIpLogForm';
import CdnDomainForm from './CdnDomainForm';

type VpnServerFormProps = {
  visible: boolean;
  defaultGroupIds: string[] | undefined;
  loadNodeId: string | undefined;
  // current: API.VpnServer | undefined;
  checks?: API.VpnServerCheckIpReport[] | undefined;
  onCancel: () => void;
  onSubmit: () => void | undefined;
  onSubmitReturn?: (record: API.VpnServer) => void;
};

const VpnServerForm: React.FC<VpnServerFormProps> = (props) => {
  const { visible, defaultGroupIds, checks, onCancel, onSubmit, loadNodeId, onSubmitReturn } =
    props;
  // console.log(current, loadNodeId);

  if (!visible) {
    return null;
  }

  const [formBatchRemarkVisible, setFormBatchRemarkVisible] =
    useState<boolean>(false);
  const [formChangeIpLogVisible, setFormChangeIpLogVisible] =
    useState<boolean>(false);
  const [formBatchVpnServerIpVisible, setFormBatchVpnServerIpVisible] =
    useState<boolean>(false);
  const [formBatchVpnServerOutIpVisible, setFormBatchVpnServerOutIpVisible] =
    useState<boolean>(false);
  const [formCdnDomainVisible, setFormCdnDomainVisible] =useState<boolean>(false);
  const [selectIds, setSelectIds] = useState<any[]>([]);

  const [reloadState, setReloadState] = useState<number | undefined>(undefined);
  const [currentLoadNode, setCurrentLoadNode] = useState<API.VpnServer | undefined>(undefined);

  const formRef = useRef<ProFormInstance>();
  const editorFormRef = useRef<EditableFormInstance<API.VpnServerNet>>();
  const editorActionRef = useRef<ActionType>();
  const editorCdnFormRef = useRef<EditableFormInstance<API.VpnServerCdn>>();
  const editorCdnActionRef = useRef<ActionType>();

  const { supplierOptions, getVpnGroupExTrees,getDeployConfigOptions,reloadCdnDomains,reloadCdnAccounts,getCdnDomainOptions,getCdnAccountOptions } = useModel(
    'useGlobalModel',
    (model) => ({
      // getVpnGroupTrees: model.getVpnGroupTrees,
      supplierOptions: model.supplierOptions,
      // getProductOptions: model.getProductOptions,
      // getProductVpnGroupTrees: model.getProductVpnGroupTrees,
      getVpnGroupExTrees: model.getVpnGroupExTrees,
      getDeployConfigOptions: model.getDeployConfigOptions,
      reloadCdnDomains: model.reloadCdnDomains,
      getCdnDomainOptions: model.getCdnDomainOptions,
      reloadCdnAccounts: model.reloadCdnAccounts,
      getCdnAccountOptions: model.getCdnAccountOptions,
    }),
  );

  const loadGroupTreeData = async (params: any) => {
    // console.log(params);getProductVpnGroupTrees(params?.productId);//
    const treeData = getVpnGroupExTrees(params?.productId);
    // if (treeData && treeData.length > 0) {
    //   for (let td of treeData) {
    //     td.children.sort((a, b) => {
    //       return (a.disabled ? 1 : 0) - (b.disabled ? 1 : 0);
    //     });
    //   }
    // }

    return Promise.resolve(treeData);
  };

  const getRandomPort = () => {
    return Math.floor(Math.random() * 10000 + 10000);
  };
  
  let rndDefPort = getRandomPort();

  // const getRandomId = () => {
  //   return (Math.random() * 100000000).toFixed(0);
  // };
  // const getUniqueId = (datas: API.VpnServerNet[]) => {
  //   let id = getRandomId();
  //   let isOnlyId = true;
  //   while (true) {
  //     for (let item of datas) {
  //       if (item.id == id) {
  //         isOnlyId = false;
  //         break;
  //       }
  //     }
  //     if (isOnlyId) {
  //       break;
  //     } else {
  //       id = getRandomId();
  //     }
  //   }
  //   return id;
  // };
  
  // let defaultData: API.VpnServerNet[] =
  //   current && current.netConfig ? current.netConfig : [];

  // let defaultCurrent: Partial<API.VpnServer> | undefined = undefined;
  // if (!current) {
  //   let rndDefPort = getRandomPort();
  //   defaultCurrent = {
  //     port: rndDefPort + 1, //16231,
  //     pingPort: rndDefPort, //16230,
  //     maxUser: 0,
  //     maxBandwidth: 0,
  //     maxUserBandwidth: 0,
  //     status: true,
  //   };
  //   if (defaultGroupIds) {
  //     defaultCurrent.groupIds = defaultGroupIds;
  //   }
  // } else {
  //   if (!current.maxUserBandwidth) {
  //     current.maxUserBandwidth = 0;
  //   }
  // }

  // const [editableKeys, setEditableRowKeys] = useState<React.Key[]>(() =>
  //   defaultData.map((item) => item.id),
  // );
  // const [dataSource, setDataSource] = useState<API.VpnServerNet[]>(
  //   () => defaultData,
  // );

  const [editableKeys, setEditableKeys] = useState<React.Key[]>([]);
  const [dataSource, setDataSource] = useState<API.VpnServerNet[]>([]);
  const [editableCdnKeys, setEditableCdnKeys] = useState<React.Key[]>([]);
  const [cdnDataSource, setCdnDataSource] = useState<API.VpnServerCdn[]>([]);

  const handleIpsSubmit = async (
    ips: string,
    status: boolean,
    change: boolean,
  ) => {
    if (ips == undefined || ips == '') return;
    ips = ips.replaceAll('\r', '');
    let iplist = ips.split('\n');
    let rows: API.VpnServerNet[] = [];
    for (let item of dataSource) {
      // console.log("old ip:" + item.ip);
      rows.push(item);
    }

    let tmpId: number = Date.now();
    for (let ip of iplist) {
      // console.log("new ip:" + ip);
      let record: API.VpnServerNet = {
        id: tmpId.toFixed(), //getUniqueId(rows),
        ip: ip,
        status: status,
        change: change,
      };
      rows.push(record);
      tmpId++;
    }

    // console.log(rows);

    setEditableKeys(() => rows.map((item) => item.id));
    setDataSource(rows);
    setFormBatchVpnServerIpVisible(false);
    editorActionRef.current.reload();
  };

  const handleOutIpsSubmit = async (
    ips: string,
    outIps: string,
    status: boolean,
    change: boolean,
  ) => {
    if (ips == undefined || ips == '') return;
    if (outIps == undefined || outIps == '') return;

    ips = ips.replaceAll('\r', '');
    let iplist = ips.split('\n').filter((element) => {
      if (Object.keys(element).length !== 0) {
        return true;
      }
      return false;
    });

    outIps = outIps.replaceAll('\r', '');
    let outIpList = outIps.split('\n').filter((element) => {
      if (Object.keys(element).length !== 0) {
        return true;
      }
      return false;
    });

    let tmpId: number = Date.now();
    let rows: API.VpnServerNet[] = [];
    for (let item of dataSource) {
      let pos = iplist.indexOf(item.ip);
      if (pos != -1) {
        let record = getNewItem(item, tmpId);
        record.relay = false;
        iplist.splice(pos, 1);
        rows.push(record);
        tmpId++;
        continue;
      }

      pos = outIpList.indexOf(item.ip);
      if (pos != -1) {
        let record = getNewItem(item, tmpId);
        record.relay = true;
        outIpList.splice(pos, 1);
        rows.push(record);
        tmpId++;
        continue;
      }

      let record = getNewItem(item, tmpId);
      rows.push(record);
      tmpId++;
    }

    for (let d of iplist) {
      let record = getNewItem(
        {
          id: '0',
          ip: d,
          relay: false,
          status: status,
          change: change,
        },
        tmpId,
      );
      rows.push(record);
      tmpId++;
    }

    for (let d of outIpList) {
      let record = getNewItem(
        {
          id: '0',
          ip: d,
          relay: true,
          status: status,
          change: change,
        },
        tmpId,
      );
      rows.push(record);
      tmpId++;
    }

    // console.log(rows);

    setEditableKeys(() => rows.map((item) => item.id));
    setDataSource(rows);
    setFormBatchVpnServerOutIpVisible(false);
    editorActionRef.current.reload();
  };

  const handleChangeChangeStatus = async () => {
    if (dataSource.length == 0) return;
    let status = true;
    status = !dataSource[0].change;
    //console.log(status);

    let tmpId: number = Date.now();
    let rows: API.VpnServerNet[] = [];
    for (let item of dataSource) {
        let newItem = getNewItem(item, tmpId);
        newItem.change = status;
        rows.push(newItem);
        tmpId++;
    }
    setEditableKeys(() => rows.map((item) => item.id));
    setDataSource(rows);
    setReloadState(Date.now);
    // editorActionRef.current.reload();
  };

  const handleChangeStatus = async () => {
    if (dataSource.length == 0) return;
    let status = true;
    status = !dataSource[0].status;
    //console.log(status);

    let tmpId: number = Date.now();
    let rows: API.VpnServerNet[] = [];
    for (let item of dataSource) {
      let newItem = getNewItem(item, tmpId);
      newItem.status = status;
      rows.push(newItem);
      tmpId++;
    }
    setEditableKeys(() => rows.map((item) => item.id));
    setDataSource(rows);
    setReloadState(Date.now);
    // editorActionRef.current.reload();
  };

  const handleBatchRemoveIps = async (onCleanSelected: any) => {
    if (dataSource.length == 0) return;

    let tmpId: number = Date.now();
    let rows: API.VpnServerNet[] = [];
    for (let item of dataSource) {
      if (selectIds.includes(item.id)) continue;
      let newItem = getNewItem(item, tmpId);
      rows.push(newItem);
      tmpId++;
    }
    setEditableKeys(() => rows.map((item) => item.id));
    setDataSource(rows);
    setSelectIds([]);
    onCleanSelected();
    editorActionRef.current.reload();
  };

  // const handleBatchBlockedIps = async () => {
  //   if (dataSource.length == 0) return;

  //   let tmpId: number = Date.now();
  //   let rows: API.VpnServerNet[] = [];
  //   for (let item of dataSource) {
  //     if (selectIds.includes(item.id)) {
  //       let newItem = getNewItem(item, tmpId);
  //       newItem.blocked = true;
  //       rows.push(newItem);
  //       tmpId++;
  //     } else {
  //       rows.push(item);
  //     }
  //   }
  //   // console.log(rows);
  //   setEditableRowKeys(() => rows.map((r) => r.id));
  //   setDataSource(rows);
  //   setSelectIds([]);
  //   editorActionRef.current?.clearSelected?.();
  //   editorActionRef.current.reload();
  // };

  const handleFormBatchRemarkSubmit = async (
    remark: string,
    status?: string,
    blocked?: string,
    change?: string,
    relay?: string,
    // maxBandwidth?: string,
  ) => {
    if (dataSource.length == 0) return;

    let tmpId: number = Date.now();
    let rows: API.VpnServerNet[] = [];
    for (let item of dataSource) {
      if (selectIds.includes(item.id)) {
        let newItem = getNewItem(item, tmpId);
        newItem.status =
          status === '0' ? false : status == '1' ? true : item.status;
        newItem.change =
          change === '0' ? false : change == '1' ? true : item.change;
        newItem.remark = remark
          ? `${item.remark ?? ''} ${remark}`
          : item.remark;
        newItem.blocked =
          blocked === '0' ? false : blocked == '1' ? true : item.blocked;
        newItem.relay =
          relay === '0' ? false : relay == '1' ? true : item.relay;
        // newItem.maxBandwidth = iMaxBandwidth ?? item.maxBandwidth;
        rows.push(newItem);
        tmpId++;
      } else {
        rows.push(item);
      }
    }
    // console.log(rows);
    setEditableKeys(() => rows.map((r) => r.id));
    setDataSource(rows);
    setSelectIds([]);
    setFormBatchRemarkVisible(false);
    editorActionRef.current?.clearSelected?.();
    editorActionRef.current.reload();
  };

  // const handleBatchChangeStatus = async (status: boolean) => {
  //   if (dataSource.length == 0) return;

  //   let tmpId: number = Date.now();
  //   let rows: API.VpnServerNet[] = [];
  //   for (let item of dataSource) {
  //     if (selectIds.includes(item.id)) {
  //       let newItem = getNewItem(item, tmpId);
  //       newItem.status = status;
  //       rows.push(newItem);
  //       tmpId++;
  //     } else {
  //       rows.push(item);
  //     }
  //   }
  //   // console.log(rows);
  //   setEditableRowKeys(() => rows.map((r) => r.id));
  //   setDataSource(rows);
  //   setSelectIds([]);
  //   editorActionRef.current?.clearSelected?.();
  //   editorActionRef.current.reload();
  // };

  // const handleBatchChangeChange = async (change: boolean) => {
  //   if (dataSource.length == 0) return;

  //   let tmpId: number = Date.now();
  //   let rows: API.VpnServerNet[] = [];
  //   for (let item of dataSource) {
  //     if (selectIds.includes(item.id)) {
  //       let newItem = getNewItem(item, tmpId);
  //       newItem.change = change;
  //       rows.push(newItem);
  //       tmpId++;
  //     } else {
  //       rows.push(item);
  //     }
  //   }
  //   // console.log(rows);
  //   setEditableRowKeys(() => rows.map((r) => r.id));
  //   setDataSource(rows);
  //   setSelectIds([]);
  //   editorActionRef.current?.clearSelected?.();
  //   editorActionRef.current.reload();
  // };

  const getNewItem = (item: API.VpnServerNet, newId: number) => {
    return {
      id: newId.toString(),
      ip: item.ip,
      outIp: item.outIp,
      outBindIp: item.outBindIp,
      relay: item.relay,
      status: item.status,
      change: item.change,
      changeStart: item.changeStart,
      changeEnd: item.changeEnd,
      blocked: item.blocked,
      blockedTime: item.blockedTime,
      remark: item.remark,
      // maxBandwidth: item.maxBandwidth,
    };
  };

  const handleUpdateRecord = async (record: API.VpnServerNet) => {
    if (dataSource.length == 0 || !record) return;
    // console.log(record);

    let rows: API.VpnServerNet[] = [];
    for (let item of dataSource) {
      if (item.id == record.id) {
        rows.push(record);
      } else {
        rows.push(item);
      }
    }
    let keys = rows.map((r) => r.id);
    setEditableKeys(keys);
    setDataSource(rows);
    editorActionRef.current.reload();
  };

  const handleFormSubmit = async (record: API.VpnServer) => {
    //record.netConfig = dataSource;
    // console.log(record, currentLoadNode,{
    //   ...currentLoadNode,
    //   ...record,
    // });
    // return;
    record.cdns = cdnDataSource;
    record.netConfig = dataSource;
    if(record.serverInfo){
      record.serverInfo.sshPassword = formRef.current?.getFieldValue(['serverInfo', 'sshPasswordNow']);
    }
    // console.log(record);
    // return;
    let result: API.Result;
    if (currentLoadNode) {
      result = await api.update({
        ...currentLoadNode,
        ...record,
      });
    } else {
      if(onSubmitReturn){
        onSubmitReturn(record);
      }
      else{
        result = await api.add({ ...record });
      }
    }

    if (result && result.success === true) {
      if(onSubmit){
        onSubmit();
      }
    }

  };

  const getCheckReportStatus = (ip: string) => {
    let text = '';
    let len = checks?.length ?? 0;
    for (let i = 0; i < len; i++) {
      if (checks && checks[i].client == ip) {
        text += checks[i].tcp ? '' : ' T';
        text += checks[i].udp ? '' : ' U';
        break;
      }
    }
    return text;
  };

  const handleClearAllIps = async () => {
    if (dataSource.length == 0) return;
    setEditableKeys([]);
    setDataSource([]);
    setSelectIds([]);
    editorActionRef.current.clearSelected();
    editorActionRef.current.reload();
  };
  
  const copySelectedIps = async () => {
    if (dataSource.length == 0) return;

    let ips: string[] = [];
    for (let item of dataSource) {
      if (selectIds.includes(item.id)) {
        ips.push(item.ip);
      }
    }
    // console.log(ips.join('\n'));
    navigator.clipboard.writeText(ips.join('\n'));
    message.info("复制成功");
  };

  const getSshUserOptions = () => {
    let options = getDeployConfigOptions(3);
    return options.map((element) => {
      return {label:element.label, value: element.value};
    });
  }

  const loadDataNet = async (params: any,sort: any,filter: any,) => {
    return { ...params, data: dataSource };
  };
  
  const loadData = async () => {

    await reloadCdnAccounts();
    await reloadCdnDomains();

    // console.log(loadNodeId);
    if (loadNodeId) {
      const result = await api.get({ key: loadNodeId });
      // console.log(result);
      if (result && result.success) {
        setDataSource(result.data.netConfig ?? []);
        setEditableKeys(result.data.netConfig?.map((val)=> val.id));
        setCdnDataSource(result.data.cdns ?? []);
        setEditableCdnKeys(result.data.cdns?.map((val)=> val.id));
        setCurrentLoadNode(result.data);
        return Promise.resolve(result.data);
      }
      return Promise.resolve(undefined);      
    } 
    else {
      // setDataSource(current?.netConfig ?? []);
      // setEditableRowKeys(current?.netConfig?.map((val)=> val.id));
      // return Promise.resolve(true);
      setDataSource([]);
      setEditableKeys([]);
      setCdnDataSource([]);
      setEditableCdnKeys([]);
      return Promise.resolve(true);
    }
  };
  
  const handleViewServerInfo = async () => {
    if (loadNodeId) {
      const result = await api.getInfo({ key: loadNodeId });
      // console.log(result);
      if (result && result.success) {
        formRef.current?.setFieldValue(['serverInfo', 'sshPasswordNow'], result.sshPassword);
        return Promise.resolve(result);
      }
      return Promise.resolve(true);      
    } 
  };

  const handleCdnDomainSubmit = async (record?: API.VpnServerCdn) => {
    if (!record) return;
    
    let rows: API.VpnServerCdn[] = [];
    for (let item of cdnDataSource) {
      rows.push(item);
    }

    rows.push(record);

    // console.log(rows);

    setEditableCdnKeys(() => rows.map((item) => item.id));
    setCdnDataSource(rows);
    setFormCdnDomainVisible(false);
    // editorCdnActionRef.current.reload();
  };

  const handleClearAllCdnDomains = async () => {
    if (cdnDataSource.length == 0) return;
    setEditableCdnKeys([]);
    setCdnDataSource([]);
    // editorCdnActionRef.current.clearSelected();
    // editorCdnActionRef.current.reload();
  };
  

  const netConfigColumns: ProColumns<API.VpnServerNet>[] = [
    {
      title: '绑定IP',
      dataIndex: 'ip',
      width: 140,
      sorter: (a, b) => (a.ip ?? '').localeCompare(b.ip ?? ''),
      formItemProps: () => {
        return {
          rules: [
            { required: true, message: '请输入绑定IP' },
            {
              pattern: pattern.IP,
              message: '请输入有效的绑定IP地址',
            },
          ],
        };
      },
      fieldProps: {
        allowClear: false,
      },
    },
    {
      title: '公网IP',
      dataIndex: 'outIp',
      width: 140,
      sorter: (a, b) => (a.outIp ?? '').localeCompare(b.outIp ?? ''),
      formItemProps: () => {
        return {
          rules: [
            {
              pattern: pattern.IP,
              message: '请输入有效的公网IP地址',
            },
          ],
        };
      },
      fieldProps: {
        allowClear: false,
      },
    },
    // {
    //   title: '限速(Mb)',
    //   dataIndex: 'maxBandwidth',
    //   width: 90,
    //   valueType: 'digit',
    //   initialValue: 0,
    //   fieldProps: {
    //     allowClear: false,
    //     required: true,
    //     precision: 0,
    //     style: { width: 80 },
    //   },
    // },
    // {
    //   title: '出口绑定IP',
    //   dataIndex: 'outBindIp',
    //   width: 140,
    //   sorter: (a, b) => (a.outBindIp ?? '').localeCompare(b.outBindIp ?? ''),
    //   formItemProps: () => {
    //     return {
    //       rules: [
    //         {
    //           pattern: pattern.IP,
    //           message: '请输入有效的出口IP地址',
    //         },
    //       ],
    //     };
    //   },
    //   fieldProps: {
    //     allowClear: false,
    //   },
    // },
    {
      title: '检测',
      dataIndex: 'check',
      readonly: true,
      width: 60,
      hideInTable: checks ? false : true,
      sorter: (a, b) =>
        getCheckReportStatus(a.ip).localeCompare(getCheckReportStatus(b.ip)),
      renderText: (_, record) => {
        return getCheckReportStatus(record.ip);
        // let text = '';
        // let len = checks?.length ?? 0;
        // for (let i = 0; i < len; i++) {
        //   if (checks && checks[i].client == record.ip) {
        //     text += checks[i].tcp ? '' : ' T';
        //     text += checks[i].udp ? '' : ' U';
        //     // text =(<>
        //     //   <Tag color={checks[i].tcp ? "success" : "error"} style={{margin:0}}>T</Tag>
        //     //   <Tag color={checks[i].udp ? "success" : "error"} style={{margin:0}}>U</Tag>
        //     // </>);
        //     break;
        //   }
        // }
        // return text;
      },
    },
    {
      title: (
        <a
          onClick={() => {
            handleChangeStatus();
          }}
        >
          <CheckSquareOutlined />
          状态
        </a>
      ),
      //title: '状态',
      dataIndex: 'status',
      valueType: 'switch',
      sorter: (a, b) => (a.status == true ? 1 : 0) - (b.status == true ? 1 : 0),
      width: 75,
      // render:(_, record) =>{
      //   return (record.status == true ? <Badge count={<CheckCircleFilled style={{ color: '#52c41a' }} />} /> : <Badge count={<CloseCircleFilled style={{ color: 'orange' }} />} />)
      // }
    },
    {
      title: (
        <a
          onClick={() => {
            handleChangeChangeStatus();
          }}
        >
          <CheckSquareOutlined />
          切换
        </a>
      ),
      // title:'切换',
      dataIndex: 'change',
      valueType: 'switch',
      sorter: (a, b) => (a.change == true ? 1 : 0) - (b.change == true ? 1 : 0),
      width: 75,
      // render:(_, record) =>{
      //   return (record.change == true ? <Badge count={<CheckCircleFilled style={{ color: '#52c41a' }} />} /> : <Badge count={<CloseCircleFilled style={{ color: 'orange' }} />} />)
      // }
    },
    {
      title: '出口IP',
      dataIndex: 'relay',
      valueType: 'switch',
      sorter: (a, b) => (a.relay == true ? 1 : 0) - (b.relay == true ? 1 : 0),
      width: 75,
    },
    {
      title: '被墙',
      dataIndex: 'blocked',
      valueType: 'switch',
      // readonly: true,
      hideInTable: !currentLoadNode,
      sorter: (a, b) =>
        (a.blocked == true ? 1 : 0) - (b.blocked == true ? 1 : 0),
      width: 60,
      // renderText:(_, record) =>{
      //   return (record.blocked == true ? <><Badge count={<CloseCircleFilled style={{ color: 'red', marginTop:-3 }} />} />{record.blockedTime ? dayjs(record.blockedTime).format('YYYY-MM-DD') : ''}</> : <></>)
      // }
    },
    {
      title: '被墙日期',
      dataIndex: 'blockedTime',
      // valueType: 'switch',
      readonly: true,
      hideInTable: !currentLoadNode,
      sorter: (a, b) =>
        dayjs(a.blockedTime)
          .format('YYYY-MM-DD HH:mm:ss')
          .localeCompare(dayjs(b.blockedTime).format('YYYY-MM-DD HH:mm:ss')),
      width: 90,
      renderText: (_, record) => {
        return record.blockedTime
          ? dayjs(record.blockedTime).format('YYYY-MM-DD')
          : '';
        //return (record.blocked == true ? <Badge count={<CloseCircleFilled style={{ color: 'red' }} />} /> : <Badge count={<CloseCircleFilled style={{ color: 'red' }} />} />)
      },
    },
    {
      title: 'IP切换',
      dataIndex: 'changeStartAndEnd',
      readonly: true,
      width: 150,
      renderText: (_, record) => {
        return `${record.changeStart ? record.changeStart : ''}-${
          record.changeEnd ? record.changeEnd : ''
        }`;
      },
    },
    // {
    //   title: '切换开始',
    //   dataIndex: 'changeStart',
    //   width: 150,
    //   readonly: true,
    // },
    // {
    //   title: '切换结束',
    //   dataIndex: 'changeEnd',
    //   width: 150,
    //   readonly: true,
    // },
    {
      title: '备注',
      sorter: (a, b) => (a.remark ?? '').localeCompare(b.remark ?? ''),
      dataIndex: 'remark',
      fieldProps: {
        allowClear: false,
      },
    },
    {
      title: '操作',
      valueType: 'option',
      width: 50,
      // render: (text, record, _, action) => [
      //   <a
      //     key="editable"
      //     onClick={() => {
      //       action?.startEditable?.(record.id);
      //     }}
      //   >
      //     编辑
      //   </a>,
      //   <Popconfirm
      //     key="delete"
      //     title="确定要删除吗?"
      //     onConfirm={async () => {
      //       const tableDataSource = formRef.current?.getFieldValue(
      //         'netConfig',
      //       ) as API.VpnServerNet[];
      //       formRef.current?.setFieldsValue({
      //         netConfig: tableDataSource?.filter(
      //           (item) => item.id !== record.id,
      //         ),
      //       });
      //     }}
      //   >
      //     <a>删除</a>
      //   </Popconfirm>,
      // ],
    },
  ];

  const cdnConfigColumns: ProColumns<API.VpnServerCdn>[] = [
    {
      title: '提供商',
      dataIndex: 'type',
      width: 150,
      valueType: 'select',
      fieldProps: {
        options: c.CdnSupplierTypeOptions,
      },
      readonly:true,
    },
    {
      title: '帐号',
      dataIndex: 'accountId',
      width: 150,
      valueType: 'select',
      fieldProps: {
        options: getCdnAccountOptions(),
      },
      readonly:true,
    },
    // {
    //   title: '域名',
    //   dataIndex: 'domainId',
    //   width: 300,
    //   sorter: (a, b) => (a.domain ?? '').localeCompare(b.domain ?? ''),
    //   valueType: 'select',
    //   fieldProps: {
    //     options: getCdnDomainOptions(),
    //   },
    //   readonly: true,
    // },
    {
      title: '名称',
      dataIndex: 'name',
      // width: 140,
      sorter: (a, b) => (a.name ?? '').localeCompare(b.name ?? ''),
      readonly: true,
    },
    {
      title: '操作',
      valueType: 'option',
      width: 50,
    },
  ];

  return (
    <DrawerForm<API.VpnServer>
      open={visible}
      initialValues={currentLoadNode}
      title={`${loadNodeId ? '编辑' : '添加'}服务器`}
      formRef={formRef}
      autoFocusFirstInput
      width={1224}
      onFinish={handleFormSubmit}
      request={loadData}
      drawerProps={{
        // forceRender: true,
        // destroyOnClose: true,
        // closable: false,
        onClose: onCancel,
        maskClosable: false,
      }}
    >
      <Row gutter={24}>
        <Col span={12}>
          <ProFormText
            name="name"
            label="名称"
            rules={[{ required: true, message: '请输入名称' }]}
            placeholder="请输入名称"
          />
        </Col>
        <Col span={12}>
          <ProFormTreeSelect
            name="groupIds"
            label="分组"
            placeholder="请选择分组"
            allowClear={false}
            // secondary
            rules={[{ required: true, message: '请选择分组' }]}
            request={loadGroupTreeData}
            // tree-select args
            fieldProps={{
              showArrow: true,
              showSearch: true,
              treeCheckable: true,
              maxTagCount: 1,
              multiple: true,
              treeDefaultExpandAll: true,
              listHeight: 600,
              treeNodeLabelProp: 'title',
              filterTreeNode: (input, option) =>
                option && option.title
                  ? option.title
                      .toString()
                      .toLowerCase()
                      .indexOf(input.toLowerCase()) >= 0
                  : false,
            }}
          />
        </Col>
      </Row>
      <Row gutter={24}>
        <Col span={3}>
          <ProFormDigit
            name="instanceId"
            label="实例ID"
            min={1}
            max={2099999999}
            rules={[{ required: true, message: '请输入实例ID' }]}
            placeholder="请输入实例ID"
          />
        </Col>
        <Col span={4}>
          <ProFormText
            name="ip"
            label="IP"
            rules={[
              { required: true, message: '请输入IP' },
              // {
              //   pattern: pattern.IP,
              //   message: '请输入有效的IP地址',
              // },
            ]}
            placeholder="请输入IP"
          />
        </Col>
        <Col span={3}>
          <ProFormDigit
            name="port"
            label="服务端口"
            min={1}
            max={65535}
            rules={[{ required: true, message: '请输入服务端口' }]}
            placeholder="请输入服务端口"
            initialValue={rndDefPort + 1}
          />
        </Col>
        <Col span={3}>
          <ProFormDigit
            name="pingPort"
            label="测速端口"
            min={0}
            max={65535}
            rules={[{ required: true, message: '请输入测速端口' }]}
            placeholder="请输入测速端口"
            initialValue={rndDefPort}
          />
        </Col>
        <Col span={3}>
          <ProFormDigit
            name="maxUser"
            label="用户限制"
            min={0}
            max={10000}
            rules={[{ required: true, message: '请输入用户限制' }]}
            placeholder="最大在线用户数量"
            initialValue={0}
          />
        </Col>
        <Col span={3}>
          <ProFormDigit
            name="maxBandwidth"
            label="总调度带宽"
            min={0}
            max={102400}
            rules={[{ required: true, message: '请输入带宽限制' }]}
            placeholder="服务器最大带宽"
            addonAfter={<span className="ant-form-item-extra">Mb</span>}
            initialValue={0}
          />
        </Col>
        <Col span={3}>
          <ProFormDigit
            name="maxIpBandwidth"
            label="单IP最大带宽"
            min={0}
            max={102400}
            rules={[{ required: true, message: '请输入用户带宽限制' }]}
            placeholder="用户最大带宽"
            addonAfter={<span className="ant-form-item-extra">Mb</span>}
            initialValue={0}
          />
        </Col>
        {/* <Col span={3}>总带宽限制
          <ProFormDigit
            name="maxUserBandwidth"
            label="用户带宽限制"
            min={0}
            max={102400}
            rules={[{ required: true, message: '请输入用户带宽限制' }]}
            placeholder="用户最大带宽"
            addonAfter={<span className="ant-form-item-extra">Kb</span>}
            initialValue={0}
          />
        </Col> */}
        <Col span={2}>
          <ProFormSwitch
            name="status"
            label="状态"
            fieldProps={{
              defaultChecked: true,
            }}
            initialValue={true}
          />
        </Col>
      </Row>
      <Row gutter={24}>
        <Col span={3}>
          <ProFormSelect
            name="serverType"
            label="服务器类型"
            placeholder="请选择服务器类型"
            allowClear={true}
            options={c.ServerTypes}
          />
        </Col>
        <Col span={4}>
          <ProFormSelect
            name="supplierId"
            label="服务器供应商"
            placeholder="请选择服务器供应商"
            allowClear={true}
            options={supplierOptions}
            fieldProps={{
              showArrow: true,
              showSearch: true,
            }}
          />
        </Col>
        <Col span={7}>
          <ProFormText
            name={['serverInfo', 'serverName']}
            label="服务器标识(与运营商对应)"
          />
        </Col>
        <Col span={5}>
          <ProFormText
            name={['serverInfo', 'serverRegion']}
            label="服务器区域(与运营商对应)"
          />
        </Col>
        <Col span={2}>
          <ProFormSwitch
            name="blockedIp"
            // hidden={!currentLoadNode}
            label="被墙"
            fieldProps={{
              defaultChecked: false,
            }}
          />
        </Col>
        <Col span={3}>
          <ProFormSwitch
            name="unscheduled"
            label="不参与分配"
          />
        </Col>
      </Row>

      <Row gutter={24}>
        <Col span={3}>
          <ProFormSelect
            name={['serverInfo', 'sshUser']}
            label="SSH用户"
            options={getSshUserOptions()}
            initialValue={currentLoadNode?.serverInfo?.sshUser}
          />
        </Col>
        <Col span={4}>
          <ProFormText
            name={['serverInfo', 'sshPasswordNow']}
            label={<>SSH密码 <a title='查看密码' onClick={handleViewServerInfo}> <EyeFilled /></a></>}
          />
        </Col>
        <Col span={3}>
          <ProFormDigit
            name={['serverInfo', 'sshPort']}
            label="SSH端口"
            min={1}
            max={65535}
            initialValue={22}
          />
        </Col>
        <Col span={4}>
          <ProFormSelect
            name={['serverInfo', 'sshKeyId']}
            label="SSH Key"
            options={getDeployConfigOptions(2)}
          />
        </Col>
        <Col span={3}>
          <ProFormSelect
            name={['serverInfo', 'workMode']}
            label="传输协议"
            rules={[{ required: true, message: '请选择传输协议' }]}
            options={[{label:'老协议', value:0},{label:'新协议', value:1}]}
            initialValue={0}
          />
        </Col>
        <Col span={2}>
          <ProFormSwitch
            name={['serverInfo', 'enableUdp']}
            label="使用UDP"
            initialValue={false}
          />
        </Col>
        <Col span={2}>
          <ProFormSwitch
            name={['serverInfo', 'auth']}
            label="开启授权"
            initialValue={false}
          />
        </Col>
        <Col span={3}>
          <ProFormSwitch
            name={['serverInfo', 'disableDeploy']}
            label="禁止自动部署"
            initialValue={false}
          />
        </Col>
      </Row>

      <Row gutter={24}>


        {/* <Col span={3}>
          <ProFormText
            name={['serverInfo', 'price']}
            label="价格"
            placeholder="请输入价格"
            initialValue={currentLoadNode?.serverInfo?.price}
          />
        </Col> */}
        <Col span={3}>
          <ProFormDateTimePicker
            name="addedDate"
            label="上架日期"
            fieldProps={{
              showTime: false,
              format: 'YYYY-MM-DD',
              defaultValue: currentLoadNode ? undefined : dayjs(),
            }}
          />
        </Col>
        <Col span={4}>
          <ProFormDigit
            name={['serverInfo', 'bandwidth']}
            label="服务器带宽"
            min={1}
            max={102400}
            addonAfter={<span className="ant-form-item-extra">Mb</span>}
          />
        </Col>
      </Row>
      <Row gutter={24}>
        <Col span={24}>
          <ProFormTextArea name="remark" label="备注" />
        </Col>
      </Row>

      <Row gutter={24}>
        <Col span={24}>
          <ProForm.Item
            name="cdns"
            label={
              <>
                CDN配置　
                <Button
                  type="primary"
                  ghost
                  onClick={() => {
                    setFormCdnDomainVisible(true);
                  }}
                >
                  添加CDN域名
                </Button>
                　
                <Popconfirm
                  key="clear_all_cdn_domains"
                  title="确定要清空CDN域名?"
                  onConfirm={async () => {
                    handleClearAllCdnDomains();
                  }}
                >
                  <Button type="primary" ghost danger>
                    清空CDN域名
                  </Button>
                </Popconfirm>

              </>
            }
          >
            <EditableProTable<API.VpnServerCdn>
              rowKey="id"
              editableFormRef={editorCdnFormRef}
              actionRef={editorCdnActionRef}
              locale={{ emptyText: '暂无数据' }}
              toolBarRender={false}
              columns={cdnConfigColumns}
              // defaultValue={cdnDataSource}
              // onChange={setDataSource}
              onChange={(value: API.VpnServerCdn[]) => {
                // console.log(value);
                setCdnDataSource(value);
              }}              
              recordCreatorProps={false}
              editable={{
                type: 'multiple',
                editableKeys: editableCdnKeys,
                actionRender: (row, config, defaultDom) => [
                  defaultDom.delete,
                ],
                // onValuesChange: (record, recordList) => {
                //   // handleUpdateRecord(record);
                // },
                onChange: setEditableCdnKeys,
              }}
              value={cdnDataSource}
              // request={loadDataNet}
              // params={{
              //   d: reloadState,
              // }}
              // rowSelection={{
              //   defaultSelectedRowKeys: [],
              //   onChange: (selectedRowKeys, selectedRows) => {
              //     setSelectIds(selectedRowKeys);
              //   },
              // }}
              pagination={{
                defaultPageSize: 20,
                pageSizeOptions: [
                  '20',
                  '100',
                  '200',
                  '300',
                  '500',
                ],
                hideOnSinglePage: false,
              }}
              tableAlertRender={({
                selectedRowKeys,
                selectedRows,
                onCleanSelected,
              }) => (
                <Space size={24}>
                  <span>
                    已选 {selectedRowKeys.length} 条记录
                    <a style={{ marginLeft: 8 }} onClick={onCleanSelected}>
                      取消选择
                    </a>
                  </span>

                  <span>
                    <Popconfirm
                      key="removeIps"
                      title="确定要批量删除IP？"
                      onConfirm={async () => {
                        // console.log(selectIds);
                        // handleChangeStatus(false);
                        handleBatchRemoveIps(onCleanSelected);
                      }}
                    >
                      <a>删除</a>
                    </Popconfirm>
                  </span>

                  <span>
                    <a
                      onClick={async () => {
                        setFormBatchRemarkVisible(true);
                      }}
                    >
                      批量修改
                    </a>
                  </span>

                  <span>
                    <a onClick={()=>{
                      copySelectedIps();
                    }}>复制IP</a>
                  </span>
                </Space>
              )}
            />
          </ProForm.Item>
        </Col>
      </Row>

      <Row gutter={24}>
        <Col span={24}>
          <ProForm.Item
            name="netConfig"
            label={
              <>
                网络配置　
                <Button
                  type="primary"
                  ghost
                  onClick={() => {
                    setFormChangeIpLogVisible(true);
                  }}
                >
                  IP切换记录
                </Button>
                　
                <Button
                  type="primary"
                  ghost
                  onClick={() => {
                    setFormBatchVpnServerIpVisible(true);
                  }}
                >
                  批量添加IP
                </Button>
                　
                <Button
                  type="primary"
                  ghost
                  onClick={() => {
                    setFormBatchVpnServerOutIpVisible(true);
                  }}
                >
                  批量出口绑定IP
                </Button>
                　
                <Popconfirm
                  key="clear_all_ip_settings"
                  title="确定要清除网络配置?"
                  onConfirm={async () => {
                    handleClearAllIps();
                  }}
                >
                  <Button type="primary" ghost danger>
                    清空IP
                  </Button>
                </Popconfirm>

                <span>　增加广播IP：</span>
                <Space style={{marginTop:23}}>
                  
                  <ProFormDigit
                    name="addBroadcastIpCount"
                    label=""
                    min={1}
                    max={100}
                    width={100}
                    allowClear={true}
                  />
                </Space>
              </>
            }
          >
            <EditableProTable<API.VpnServerNet>
              rowKey="id"
              editableFormRef={editorFormRef}
              actionRef={editorActionRef}
              locale={{ emptyText: '暂无数据' }}
              toolBarRender={false}
              columns={netConfigColumns}
              defaultValue={dataSource}
              // onChange={setDataSource}
              onChange={(value: API.VpnServerNet[]) => {
                // console.log(value);
                setDataSource(value);
              }}
              recordCreatorProps={{
                // newRecordType: 'cache',
                newRecordType: 'dataSource',
                position: 'bottom',
                record: () => ({
                  id: (Math.random() * 1000000).toFixed(0),
                  ip: '0.0.0.0',
                  status: false,
                  change: false,
                  // portBegin: 16231,
                  // portEnd: 16234,
                }),
              }}
              editable={{
                type: 'multiple',
                //type: 'single',
                editableKeys,
                actionRender: (row, config, defaultDom) => [
                  //defaultDom.save,
                  defaultDom.delete,
                ],
                onValuesChange: (record, recordList) => {
                  // console.log(record, recordList);
                  // setDataSource(recordList);
                  handleUpdateRecord(record);
                },
                onChange: setEditableKeys,
              }}
              // request={async () => ({
              //   data: dataSource,
              //   current: curPage,
              //   pageSize: 20,
              //   success: true,
              // })}
              request={loadDataNet}
              params={{
                d: reloadState,
              }}
              rowSelection={{
                defaultSelectedRowKeys: [],
                onChange: (selectedRowKeys, selectedRows) => {
                  setSelectIds(selectedRowKeys);
                },
              }}
              pagination={{
                defaultPageSize: 20,
                pageSizeOptions: [
                  '20',
                  '100',
                  '200',
                  '300',
                  '500',
                  '1000',
                  '2000',
                  '5000',
                  '10000',
                ],
                hideOnSinglePage: false,
                //current: curPage,
                // total: totalCount,
                // onChange:(page:number, pageSize: number) => {
                //   console.log(page, pageSize);
                //   setCurPage(page);
                // }
              }}
              tableAlertRender={({
                selectedRowKeys,
                selectedRows,
                onCleanSelected,
              }) => (
                <Space size={24}>
                  <span>
                    已选 {selectedRowKeys.length} 条记录
                    <a style={{ marginLeft: 8 }} onClick={onCleanSelected}>
                      取消选择
                    </a>
                  </span>

                  <span>
                    <Popconfirm
                      key="removeIps"
                      title="确定要批量删除IP？"
                      onConfirm={async () => {
                        // console.log(selectIds);
                        // handleChangeStatus(false);
                        handleBatchRemoveIps(onCleanSelected);
                      }}
                    >
                      <a>删除</a>
                    </Popconfirm>
                  </span>

                  <span>
                    <a
                      onClick={async () => {
                        setFormBatchRemarkVisible(true);
                      }}
                    >
                      批量修改
                    </a>
                  </span>

                  <span>
                    <a onClick={()=>{
                      copySelectedIps();
                    }}>复制IP</a>
                  </span>
                </Space>
              )}
            />
          </ProForm.Item>
        </Col>
      </Row>

      <VpnServerChangeIpLogForm
        visible={formChangeIpLogVisible}
        current={currentLoadNode}
        onCancel={() => {
          setFormChangeIpLogVisible(false);
        }}
      />
      <BatchVpnServerIpForm
        visible={formBatchVpnServerIpVisible}
        current={currentLoadNode}
        onSubmit={handleIpsSubmit}
        onCancel={() => {
          setFormBatchVpnServerIpVisible(false);
        }}
      />
      <VpnServerBatchRemarkForm
        visible={formBatchRemarkVisible}
        onSubmit={handleFormBatchRemarkSubmit}
        onCancel={() => {
          setFormBatchRemarkVisible(false);
        }}
      />
      <BatchVpnServerOutIpForm
        visible={formBatchVpnServerOutIpVisible}
        current={currentLoadNode}
        onSubmit={handleOutIpsSubmit}
        onCancel={() => {
          setFormBatchVpnServerOutIpVisible(false);
        }}
      />
      <CdnDomainForm
        visible={formCdnDomainVisible}
        onSubmit={handleCdnDomainSubmit}
        onCancel={() => {
          setFormCdnDomainVisible(false);
        }}
      />
    </DrawerForm>
  );
};

export default VpnServerForm;
